<!doctype html>
<html>
<head>
	<meta charset="UTF-8">
	<meta name="viewport"
		  content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
	<title>three.js练习</title>
	<style>
		*{margin: 0;}
		body{
			overflow: hidden;
		}
		.circle{
			z-index: 2;
			position:fixed;
			top:0;
			left:0;
			bottom:0;
			right:0;
			margin: auto;
			width: 10px;
			height: 10px;
			background-color: transparent;
			border: 2px solid red;
			border-radius: 50%;
		}
		#three-canvas{
			z-index: 1;
		}
	</style>
	<script src="http://www.huxlog.com:3001/api/threejs/three-js/three.min.js"></script>
	<script src="http://www.huxlog.com:3001/api/threejs/controls/PointerLockControls.js"></script>
</head>
<body>
<div class="circle">

</div>	
<canvas id="three-canvas"></canvas>
<script>
	let canvas = document.getElementById('three-canvas');

	//游戏数据
	let cameraState = {
		speed:0.1,
		height:2
	};
	let keyState = {//监控键盘
		a:false,
		s:false,
		d:false,
		w:false,
		[' ']:false
	} 
	let totalCubes = 30;
	let cubes = [];
	let bullets = [];//射击的子弹

	//控制canvas大小
	let Height = window.innerHeight;
	let Width = window.innerWidth;
	window.onload = resize;
	window.onresize = resize;
	function resize(){
		Height = window.innerHeight;
		Width = window.innerWidth;
		canvas.height = Height;
		canvas.Width = Width;
		//canvas改变后需要重新渲染
		renderer.setSize(Width,Height);
		camera.aspect = Width/Height
		camera.updateProjectionMatrix();
	}

	//添加渲染器
	let renderer = new THREE.WebGLRenderer({canvas});
	renderer.setSize(Width,Height);
	//渲染阴影
	renderer.shadowMap.enabled = true;

	//添加场景
	let scene = new THREE.Scene();

	//添加相机
	let camera = new THREE.PerspectiveCamera(75,Width/Height,0.01,1000);
	camera.position.set(0,cameraState.height,0);
	camera.lookAt(2,cameraState.height,2);

	//添加环境光
	let ambientlight = new THREE.AmbientLight(0xffffff,0.7);
	scene.add(ambientlight);

	//添加点光源
	let pointlight = new THREE.PointLight(0xffffff,1,1000,0.2);
	pointlight.position.set(0,20,0);
	pointlight.castShadow = true;
		scene.add(pointlight);

	//添加世界背景
	let texture = new THREE.CubeTextureLoader();
	let bg = texture.setPath('http://www.huxlog.com').load([
		'/api/imgs/34.jpg',
		'/api/imgs/31.jpg',
		'/api/imgs/35.jpg',
		'/api/imgs/32.jpg',
		'/api/imgs/36.jpg',
		'/api/imgs/33.jpg'
	]);
	scene.background = bg;

	//添加地面
	let geometry = new THREE.CircleGeometry(50,100,100);
	let material = new THREE.MeshPhongMaterial({
		color:new THREE.Color(0xffffff),
		side:THREE.DoubleSide
	});
	let ground = new THREE.Mesh(geometry,material);
	ground.rotateX(Math.PI/2);
	//接收阴影
	ground.receiveShadow = true;
	scene.add(ground);

	//添加控制器
	let controls = new THREE.PointerLockControls(camera);
	canvas.addEventListener('click',()=>{
		controls.lock();
	});
	controls.addEventListener('lock',()=>{
		console.log('游戏开始');
	});
	controls.addEventListener('unlock',()=>{
		console.log('游戏暂停');
	});


	//加一个坐标轴
	let axishelper = new THREE.AxisHelper(50);
	scene.add(axishelper);

	//键盘事件监听
	window.addEventListener('keydown',(e)=>{
		let {key} = e;
		keyState[key] = true;
	});
	window.addEventListener('keyup',(e)=>{
		let {key} = e;
		keyState[key] = false;
	});

	//摄像机移动
	function moveCamera(){
		if(keyState['w']){
			camera.translateZ(-cameraState.speed);
            camera.position.y = cameraState.height;
		}
		if(keyState['s']){
			camera.translateZ(cameraState.speed);
            camera.position.y = cameraState.height;
			
		}
		if(keyState['a']){
			camera.translateX(-cameraState.speed);
		}
		if(keyState['d']){
			camera.translateX(cameraState.speed);
		}
		if(keyState[' ']){
			console.log('跳');
		}
	}

	//创建方块
	function createCubes(){
		for(let i=0;i<100;i++){
			let x = (Math.random()-0.5)*80;
			//0.5避免陷入地面
			let y = Math.random()*15+0.5;
			let z = (Math.random()-0.5)*80;
			let geometry = new THREE.BoxGeometry(2,1,2);
			let material = new THREE.MeshPhongMaterial({
				color:new THREE.Color(0xffffff*Math.random()),
				sidr:THREE.DoubleSide
			});
			let box = new THREE.Mesh(geometry,material);
			box.position.set(x,y,z);
			box.receiveShadow = true;
			box.castShadow = true;
			let vx = Math.random()*0.03+0.01;
			let vy = Math.random()*0.03+0.01;
			let vz = Math.random()*0.03+0.01;
			cubes.push({
				box:box,
				move:{
					vx,
					vy,
					vz
				}
			});
		}
		cubes.forEach(item=>{
			scene.add(item.box);
		})
	}
	createCubes();

	//移动方块
	function moveCube(){
		cubes.forEach((item,index)=>{
			if(Math.abs(item.box.position.z)>25){
				item.move.vx *= -1;
			}
			if(item.box.position.y<0.5||item.box.position.y>15){
				item.move.vy *= -1;
			}
			if(Math.abs(item.box.position.z)>25){
				item.move.vz *= -1;
			}
			item.box.translateX(item.move.vx);
			item.box.translateY(item.move.vy);
			item.box.translateZ(item.move.vz);
		});
	}

	//射击子弹
	window.addEventListener('click',()=>{
		let geometry = new THREE.SphereGeometry(0.1,20,20);
		let material = new THREE.MeshPhongMaterial({
			color:new THREE.Color(0x222222)
		});
		let bullet = new THREE.Mesh(geometry,material);
		bullet.receiveShadow = true;
		bullet.castShadow = true;
		bullet.position.x = camera.position.x;
		bullet.position.y = camera.position.y;
		bullet.position.z = camera.position.z;
		scene.add(bullet);
		let raycaster = new THREE.Raycaster();
		raycaster.setFromCamera({
			x:0,
			y:0
		},camera);
		let direction = raycaster.ray.direction;
		bullet.translateX(direction.x);
		bullet.translateY(direction.y);
		bullet.translateZ(direction.z);
		let bulletstate = {
			x:direction.x,
			y:direction.y,
			z:direction.z,
		};
		bullets.push({
			bullet:bullet,
			state:bulletstate
		});
	});
	//移动子弹
	function moveBullets(){
		bullets.forEach((item,index)=>{
			item.bullet.translateX(item.state.x/3);
			item.bullet.translateY(item.state.y/3);
			item.bullet.translateZ(item.state.z/3);
			let raycaster = new THREE.Raycaster(item.bullet.position,item.state);
			let arr = raycaster.intersectObjects(cubes.map(cube=>cube.box));//撞击检测
			if(arr[0]&&arr[0].distance<0.8){
				scene.remove(arr[0].object);
				scene.remove(item.bullet);
				bullets.splice(index,1);
			}
			else{
				let x = Math.abs(item.bullet.position.x);
				let y = Math.abs(item.bullet.position.y);
				let z = Math.abs(item.bullet.position.z);
				if(x>100||y>100||z>100){
					scene.remove(item.bullet);
					bullets.splice(index,1);
				}
			}
		});
	}

	function animation(){
		window.requestAnimationFrame(animation);
		moveCamera();
		moveCube();
		moveBullets();
		renderer.render(scene,camera);
	}
	animation();


</script>
</body>
</html>
